home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / DOS.SWG / 0036_Get CMOS Values.pas < prev    next >
Pascal/Delphi Source File  |  1993-11-21  |  9KB  |  302 lines

  1. {
  2. From: RANDALL WOODMAN
  3. Subj: CMOS Info
  4.  
  5.   Does anyone know how to get the hard drive type(s) from CMOS ?
  6. }
  7.  
  8. USES DOS,CRT;
  9.  
  10. TYPE
  11.   String80 = STRING [80];  { some general purpose string types }
  12.   String40 = STRING [40];
  13.   String30 = STRING [30];
  14.   String20 = STRING [20];
  15.   String12 = STRING [12];
  16.   String10 = STRING [10];
  17.   String5  = STRING [5];
  18.  
  19.   CMOSRec = RECORD
  20.     Found     : BOOLEAN;  { was a CMOS found to exist }
  21.     CmosDate  : String30; { the date found in CMOS }
  22.     CmosTime  : String30; { the time found in CMOS }
  23.     VideoType : String10; { Type of video found in CMOS }
  24.     Coproc    : BOOLEAN;  { does CMOS report a math coprocessor }
  25.     FloppyA   : String12; { type of floppy drive for A }
  26.     FloppyB   : String12; { Type of floppy drive for B }
  27.     Hard0     : BYTE;     { Type of hard drive for drive 0 }
  28.     Hard1     : BYTE;     { Type of hard drive for Drive 1 }
  29.     ConvenRam : WORD;     { amount of conventional ram indicated }
  30.     ExtendRam : WORD;     { amount of extended Ram indicated }
  31.     checkSum  : BOOLEAN;  { Did checksum pass }
  32.   END; { CMOS Rec }
  33.  
  34. CONST
  35.   { values of constants for CMOS }
  36.   DayName : ARRAY [0..7] OF STRING [9] = ('Sunday', 'Monday', 'Tuesday',
  37.                                           'Wednesday', 'Thursday', 'Friday',
  38.                                           'Saturday', 'Sunday');
  39.   MonthName : ARRAY [0..12] OF STRING [9] = ('???', 'January', 'February', 'March',
  40.                                           'April', 'May', 'June', 'July',
  41.                                           'August', 'September', 'October',
  42.                                           'November', 'December');
  43.   ScreenName : ARRAY [0..3] OF STRING [10] = ('EGA/VGA', 'CGA 40col',
  44.                                            'CGA 80col', 'Monochrome');
  45.   FloppyName : ARRAY [0..5] OF STRING [11] = ('none', '5.25" 360K',
  46.                                            '5.25" 1.2M', '3.5"  720K',
  47.                                            '3.5"  1.44M', '3.5"  2.88M');
  48.   CMOSport : BYTE = $70; { port to access the CMOS }
  49.  
  50.   Country  : BYTE = 0;  { used for country date format }
  51.  
  52. {===========================================================================}
  53.  
  54.  
  55. VAR
  56.   Regs             : REGISTERS; { General purpose variable to access
  57.                                   registers }
  58.   CMOS             : CMOSRec;   { variable to hold CMOS data }
  59.  
  60. FUNCTION nocarry : BOOLEAN;
  61. { returns the status of the carry flag }
  62. BEGIN
  63.   nocarry := regs.flags AND fcarry = $0000
  64. END; {nocarry}
  65.  
  66. {---------------------------------------------------------------------------}
  67.  
  68. FUNCTION ByteToWord (ByteA, ByteB : BYTE) : WORD;
  69. BEGIN
  70.    ByteToWord := WORD (ByteB) SHL 8 + ByteA
  71. END; {cbw}
  72.  
  73. {---------------------------------------------------------------------------}
  74.  
  75. FUNCTION BitIsSet (CheckWord : WORD; AndValue : WORD) : BOOLEAN;
  76. { returns true if the bit(s) indicated in AndValue are set in CheckByte }
  77. BEGIN
  78.   BitIsSet := CheckWord AND AndValue = AndValue;
  79. END;
  80.  
  81. {---------------------------------------------------------------------------}
  82.  
  83. FUNCTION ReadCMOS (ADDR : BYTE) : BYTE;
  84. { read a value from the CMOS }
  85. BEGIN
  86.   IF CMOSport = $70 THEN
  87.   BEGIN
  88.     INLINE ($FA);
  89.     Port [CMOSport] := ADDR;
  90.     readCMOS := Port [CMOSport + 1];
  91.     INLINE ($FB)
  92.   END
  93. END; {readCMOS}
  94.  
  95. {---------------------------------------------------------------------------}
  96.  
  97. FUNCTION addzero (b : BYTE) : string5;
  98. VAR
  99.   c2 : STRING [2];
  100. BEGIN
  101.   STR (b : 0, c2);
  102.   IF b < 10 THEN
  103.     c2 := '0' + c2;
  104.   addzero := c2
  105. END; {addzero}
  106.  
  107. {---------------------------------------------------------------------------}
  108.  
  109. FUNCTION ChangeBCD (b : BYTE) : BYTE;
  110. { change a BCD into a byte structure }
  111. BEGIN
  112.   ChangeBCD := (b AND $0F) + ( (b SHR 4) * 10)
  113. END; {ChangeBCD}
  114.  
  115. {---------------------------------------------------------------------------}
  116.  
  117. FUNCTION Long2Str (Long : LONGINT) : STRING;
  118. VAR Stg : STRING;
  119. BEGIN
  120.   STR (Long, Stg);
  121.   Long2Str := Stg;
  122. END;
  123.  
  124. FUNCTION  HexL (argument : LONGINT) : STRING; Assembler;
  125.   asm
  126.      cld
  127.      les    di, @result
  128.      mov    al, 8                   { store string length }
  129.      stosb
  130.      mov    cl, 4                  { shift count }
  131.  
  132.      mov    dx, WORD PTR Argument + 2 { hi word }
  133.      call   @1                     { convert dh to ascii }
  134.      mov    dh, dl                 { lo byte of hi word }
  135.      call   @1                     { convert dh to ascii }
  136.      mov    dx, WORD PTR Argument   { lo word }
  137.      call   @1                     { convert dh to ascii }
  138.      mov    dh, dl                 { lo byte of lo word }
  139.      call   @1                     { convert dh to ascii }
  140.      jmp    @2
  141.  
  142.    @1 :
  143.      mov    al, dh                 { 1 byte }
  144.      AND    al, 0fh                { low nybble }
  145.      add    al, 90h
  146.      daa
  147.      adc    al, 40h
  148.      daa
  149.      mov    ah, al                 { store }
  150.      mov    al, dh                 { 1 byte }
  151.      SHR    al, cl                 { get high nybble }
  152.      add    al, 90h
  153.      daa
  154.      adc    al, 40h
  155.      daa
  156.      stosw                         { move characters to result }
  157.      retn                          { return near }
  158.    @2 :
  159.   END;
  160.  
  161. FUNCTION GetCMOSDate : String30;
  162. { gets the date found in the CMOS and returns it in string format }
  163. VAR
  164.   Date,
  165.   Century,
  166.   Year,
  167.   Month : BYTE;
  168.   WorkStr : String30;
  169. BEGIN
  170.   WorkStr := '';
  171.   date    := ChangeBCD (readCMOS (7) );
  172.   century := ChangeBCD (readCMOS ($32) );
  173.   year    := ChangeBCD (readCMOS (9) );
  174.   month   := ChangeBCD (readCMOS (8) );
  175.   CASE country OF
  176.     0, 3..255 :
  177.       WorkStr := WorkStr + Monthname [month] + ' ' + Long2Str (date) + ', ' + Long2Str (century) + addzero (year);
  178.     1 :
  179.       WorkStr := WorkStr + Long2Str (date) + ', ' + Monthname [month] + ' ' + Long2Str (century) + addzero (Year);
  180.     2 :
  181.       WorkStr := WorkStr + Long2Str (century) + addzero (Year) + ', ' + Monthname [month] + ' ' + Long2Str (date);
  182.   END; {case}
  183.   GetCMosDate := workStr;
  184. END; { GetCMOSDate }
  185.  
  186. {---------------------------------------------------------------------------}
  187.  
  188. FUNCTION GetCmosTime : String30;
  189. { returns the time as found in the CMOS }
  190. VAR
  191.   CH : CHAR;
  192.   Hour,
  193.   Min,
  194.   Sec  : BYTE;
  195.   WorkStr : String30;
  196.   IsPM    : BOOLEAN;
  197. BEGIN
  198.   workStr := '';
  199.   hour := ChangeBCD (readCMOS (4) );
  200.   min := ChangeBCD (readCMOS (2) );
  201.   sec := ChangeBCD (readCMOS (0) );
  202.   IsPm := FALSE;
  203.   CASE hour OF
  204.         0 : hour := 12;
  205.         1..11 : hour := hour;
  206.         12 : IsPM := TRUE;
  207.         13..23 : BEGIN
  208.                   IsPM := TRUE;
  209.                   hour := hour - 12
  210.                 END;
  211.   END; {case}
  212.   WorkStr := WorkStr + AddZero (hour) + ':' + addzero (min) + ':' + addzero (sec);
  213.   IF IsPM THEN
  214.     workStr := WorkStr + ' PM'
  215.   ELSE
  216.     WorkStr := WorkStr + ' AM';
  217.   GetCMOSTime := WorkStr;
  218. END; { GetCmosTime }
  219.  
  220. {---------------------------------------------------------------------------}
  221.  
  222. FUNCTION GetCmosCheckSum : BOOLEAN;
  223. { performs checksum on CMOS and returns true if ok }
  224. VAR
  225.   CheckSum1,
  226.   CheckSum2 : WORD;
  227.   Count     : BYTE;
  228. BEGIN
  229.   checksum1 := 0;
  230.   FOR count := $10 TO $2D DO
  231.     INC (checksum1, readCMOS (count) );
  232.   checksum2 := (WORD (256) * readCMOS ($2E) ) + readCMOS ($2F);
  233.   IF checksum1 = checksum2 THEN
  234.     GetCmosCheckSum := TRUE
  235.   ELSE
  236.     GetCmosCheckSum := FALSE;
  237. END; { GetCmosCheckSum }
  238.  
  239. {---------------------------------------------------------------------------}
  240.  
  241. PROCEDURE GetCMos;
  242. { gets the cmos record if it exist }
  243. VAR
  244.   Floppy : BYTE;
  245. BEGIN
  246.   FILLCHAR (CMOS, SIZEOF (CMos), 0);
  247.   regs.AH := $C0;
  248.   INTR ($15, regs);
  249.   IF nocarry OR (Mem [$F000 : $FFFE] <= $FC) THEN
  250.   WITH CMOS DO
  251.   BEGIN
  252.     Found := TRUE;
  253.     CMOSDate := GetCMOSDate;
  254.     CMOSTime := GetCmosTime;
  255.     VideoType := ScreenName [ (readCMOS ($14) SHR 4) AND 3];
  256.     CoProc := BitIsSet (readCMOS ($14), 1);
  257.     Floppy := readCMOS ($10);
  258.     IF (Floppy SHR 4) < 5 THEN
  259.       FloppyA := FloppyName [floppy SHR 4]
  260.     ELSE
  261.       FloppyA := 'Unknown ' + HexL (floppy SHR 4);
  262.     IF (floppy AND $0F) < 5 THEN
  263.       FloppyB := FloppyName [floppy AND $0F]
  264.     ELSE
  265.       FloppyB := 'Unknown ' + HexL (floppy AND $0F);
  266.  
  267.     Hard0 := readCMOS ($12);
  268.     Hard0 := Hard0 SHR 4;
  269.     Hard1 := ReadCmos ($12);
  270.     Hard1 := Hard1 AND $0F;
  271.     IF Hard0 = $F THEN
  272.       Hard0 := readCMOS ($19)
  273.     ELSE Hard0 := $FF; { error }
  274.     IF Hard1 = $F THEN
  275.       Hard1 := readCMOS ($1A)
  276.     ELSE Hard1 := $FF;
  277.     ConvenRam := WORD (256) * readCMOS ($16) + readCMOS ($15); { value in K }
  278.     ExtendRam := WORD (256) * readCMOS ($18) + readCMOS ($17); { value in K }
  279.     CheckSum := GetCmosCheckSum;
  280.   END
  281.   ELSE
  282.     CMOS.Found := FALSE;
  283. END;
  284.  
  285. BEGIN
  286. ClrScr;
  287. GetCMos;
  288. With CMOS DO
  289.      BEGIN
  290.      WriteLn('Date     : ',CMosDate);
  291.      WriteLn('Time     : ',CMosTime);
  292.      WriteLn('Video    : ',VideoType);
  293.      WriteLn('Math     : ',CoProc);
  294.      WriteLn('FloppyA  : ',FloppyA);
  295.      WriteLn('FloppyB  : ',FloppyB);
  296.      WriteLn('Hard #1  : ',Hard0);
  297.      WriteLn('Hard #2  : ',Hard1);
  298.      WriteLn('Base Ram : ',ConvenRam,'K');
  299.      WriteLn('Ext Ram  : ',ExtendRam,'K');
  300.      ReadKey;
  301.      END;
  302. END.